package com.lock.immersive.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lock.immersive.exception.BusinessException;
import com.lock.immersive.mapper.UserMapper;
import com.lock.immersive.pojo.domain.User;

import com.lock.immersive.pojo.dto.UserAccountDto;
import com.lock.immersive.pojo.dto.UserDto;
import com.lock.immersive.pojo.enums.LoginMethod;
import com.lock.immersive.service.UserService;
import com.lock.immersive.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author zhao
 * @description 针对表【user】的数据库操作Service实现
 * @createDate 2023-04-25 22:15:34
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private RestTemplate restTemplate;
    @Value("${miniProgram.AppID}")
    public String appId;
    @Value("${miniProgram.AppSecret}")
    public String appSecret;

    @Override
    public ResponseApi<Object> login(UserDto userDto) {
        if (userDto.getMethod().equals(LoginMethod.mobile)) {
            String phone = userDto.getPhone();
            String code = userDto.getCode();
            System.out.println(code);
            String s = (String) redisTemplate.opsForValue().get(phone);
            if (s != null) {
                if (s.equals(code)) {

                    String userId = userMapper.selectPhone(phone);
                    if (userId != null) {
                        return ResponseApi.success(JWT.getJWToken(userId));
                    } else {
                        throw new BusinessException(ErrorCode.ACCOUNT_OR_PASSWORD_INCORRECT);
                    }
                } else {
                    throw new BusinessException(ErrorCode.CODE_ERROR);
                }
            } else {
                throw new BusinessException(ErrorCode.CODE_INVALID);
            }
        } else {
            String userAccount = userDto.getUserAccount();
            String userPassword = userDto.getUserPassword();
            String userId = userMapper.selectAccount(userAccount);
            if (userId != null) {
                User user = userMapper.selectById(userId);
                if (user.getUserPassword().equals(userPassword)) {
                    return ResponseApi.success(JWT.getJWToken(userId));
                } else {
                    throw new BusinessException(ErrorCode.ACCOUNT_OR_PASSWORD_INCORRECT);
                }
            } else {
                throw new BusinessException(ErrorCode.ACCOUNT_OR_PASSWORD_INCORRECT);
            }
        }
    }

    @Override
    public ResponseApi<Object> register(UserDto userDto) {
        if (userDto.getMethod().equals(LoginMethod.mobile)) {
            String phone = userDto.getPhone();
            String code = userDto.getCode();
            System.out.println(code);
            String s = (String) redisTemplate.opsForValue().get(phone);
            if (s != null) {
                if (s.equals(code)) {

                    String userId = userMapper.selectPhone(phone);
                    if (userId != null) {
                        throw new BusinessException(ErrorCode.REGISTERED_ERROR);
                    } else {
                        String wxData = restTemplate.getForObject("https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + userDto.getJsCode() + "&grant_type=authorization_code", String.class);
                        String openid = JSON.parseObject(wxData).getString("openid");
                        User user = new User();
                        user.setOpenId(openid);
                        user.setUserPhone(phone);
                        user.setNickName(RandomNickname.getName());
                        user.setUserAvatar("https://fastly.jsdelivr.net/npm/@vant/assets/icon-demo.png");
                        int insert = userMapper.insert(user);
                        if (insert > 0) {
                            userId = userMapper.selectPhone(phone);
                            return ResponseApi.success(JWT.getJWToken(userId));
                        } else {
                            throw new BusinessException(ErrorCode.REGISTRATION_FAILED);
                        }
                    }
                } else {
                    throw new BusinessException(ErrorCode.CODE_ERROR);
                }
            } else {
                throw new BusinessException(ErrorCode.CODE_INVALID);
            }
        } else {
            String userAccount = userDto.getUserAccount();
            String userPassword = userDto.getUserPassword();
            String userId = userMapper.selectAccount(userAccount);
            if (userId != null) {
                throw new BusinessException(ErrorCode.REGISTERED_ERROR);
            } else {
                User user = new User();
                user.setUserAccount(userAccount);
                user.setUserPassword(userPassword);
                user.setNickName(RandomNickname.getName());
                user.setUserAvatar("https://fastly.jsdelivr.net/npm/@vant/assets/icon-demo.png");
                int insert = userMapper.insert(user);

                if (insert > 0) {
                    userId = userMapper.selectAccount(userAccount);
                    return ResponseApi.success(JWT.getJWToken(userId));
                } else {
                    throw new BusinessException(ErrorCode.REGISTRATION_FAILED);
                }
            }
        }
    }

    @Override
    public ResponseApi<Object> sendSMS(String phone) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 4; i++) {
            sb.append(new Random().nextInt(9));
        }
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        ops.set(phone, sb.toString(), 5, TimeUnit.MINUTES);
        try {
            SendSms.send(phone, sb.toString());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return ResponseApi.success();
    }

    @Override
    public ResponseApi<Object> updateUserInfo(User newUser) {
        User user = userMapper.selectById(newUser.getUserId());
        BeanUtils.copyProperties(newUser, user);
        int update = userMapper.updateById(user);
        if (update > 0) {
            return ResponseApi.success(RefreshToken.refresh());
        } else {
            throw new BusinessException(ErrorCode.UPDATE_ERROR);
        }
    }

    @Override
    public User getLoginUser(HttpServletRequest request) {
        String token = request.getHeader("token");
        String userId = JWT.getTokenId(token);
        return userMapper.selectById(userId);
    }


}




